//【案例开放080】0422上机编程[数据表格区域统计]学习交流
//日期：2022-04-29 16:23浏览：9462回复：132027-04-29
//失效最近编辑时间：2022-04-29 16:23
// 1.  题目
//今天学习0422专业级第二题。
// Excel工作表中对选定区域的数值进行统计的功能非常实用。仿照Excel的这个功能，请对给定表格中选中区域中单元格进行求和统计，并输出统计结果。
//为简化统计，假设当前输入中每个单元格内容仅为数字或公式两种。
// l  如果为数字，则是一个非负整数，形如 0、11
// l  如果为公式，则固定以=开头，且仅包含下面三种情况：
//Ø  等于某单元格的值，形如=B12
//Ø  两个单元格的双目运算（仅为 + 或 -），形如=C1-C2、C10+B2
//Ø  单元格和数字的双目运算（仅为 + 或 -），形如=B12+1、=100-B12
//公式不存在嵌套，例如 =C1-C2，其中C1和C2单元格的内容只会是数字，不会是公式。
//公式内容都是合法的，例如不存在“=C+2”,“=C1-C2+B3”,“=5”,“=1+10”；
//内容中不存在空格、括号 输入 第一行两个整数 rows
// cols，表示给定表格区域的行数和列数， 1 <= rows <= 20，1 <= cols <= 26 接下来
// rows 行，每行 cols 个以空格分隔的字符串，表示给定表格 values 的单元格内容
//最后一行输入的字符串，表示给定的选中区域，形如A1:C2
// l  表格的行号 1~20，列号 A~Z，例如单元格 B3 对应 values[2][1]
// l  输入的单元格内容（含公式）中的数字均为十进制，值范围 [0, 100]
// l  选中区域: 冒号左侧单元格表示选中区域的左上角，右侧表示右下角，如可以为
// B2:C10、B2:B5、B2:Y2、B2:B2，无类似 C2:B2、C2:A1 的输入 输出
//一个整数，表示选中区域的数值之和
//样例
//输入样例 1
// 5 3
// 10 12 =C5
// 15 5 6
// 7 8 =3+C2
// 6 =B2-A1 =C2
// 7 5 3
// B2:C4
//输出样例 1
// 29
//提示样例 1
//给定表格内容为5行3列，各单元格的输入数据及计算后数值，表示如下：
// https://oj.rnd.huawei.com/public/upload/8a370809dd.png
//其中几个单元格内容为公式，这几个单元格的值计算过程如下：
// C1 = C5 = 3
// C3 = 3+C2 = 3+6 = 9
// B4 = B2-A1 = 5-10 = -5
// C4 = C2 = 6
//选中区域 B2:C4 包含6个单元格（图中蓝色区域），统计结果为：5 + 8 - 5 + 6 + 9 +
// 6 = 29 输入样例 2 1 3 1 =A1+C1 3 A1:C1 输出样例 2
// 8
//提示样例 2
//选定区域为整行。B1单元格按公式计算为4，结果为1+4+3=8
// 2.  题目分析
//题目理解：
//要求实现类似EXCEL选定区域求和功能。
//给定了一个rows*cols的矩阵中单元格的内容，以及给定了选中区域的范围，需要遍历这些选中区域所有单元格并求和。
//注意有些单元格已经是数字格式，有些是公式，需要解析这些公式。
//思路解析：
//输入的整个表格是以二维数组的方式提供的，每个数组元素代表一个单元格，每个单元格cell[row][col]有两种格式：
// l  数字
// l  公式，又分为两大类
//Ø  等于某单元格的值，形如=C5 即cell[row][col]中存储的是另外一个单元格的地址。
//Ø  等于x oper y，其中x和y又可能是数字或者某个单元格的地址，操作符oper可能是
//+或者- =C5这种如何求得值呢？
//我们从题目中得知，把C5将字母和数字分开，就是C和5，分别表示第3列、第5行，即数组元素values[4][2]的值。
//这样我们就解决了如何从单元格地址取得单元格内容的这个关键问题。
//至于包含公式的单元格的求值，采取分而治之的方法即可。
//对某个单元格求值流程如下图所示：
//下面看看大家是如何实现的。
//员工2-C++代码：46行、最大圈复杂度4
#include <bits/stdc++.h>

#include <iostream>
#include <string>
#include <vector>
using namespace std;
class Solution {
 public:
  // 待实现函数，在此函数中填入答题代码;
  int GetSum(const vector<vector<string>>& values, const string& range) {
    vector<int> pos = GetRange(range);
    int m = values.size();
    int n = values.front().size();
    int sum = 0;
    for (int i = pos[1]; i < pos[3]; i++) {
      for (int j = pos[0]; j < pos[2]; j++) {
        if (values[i][j][0] == '=') {
          sum += GetRes(values, i, j);
          continue;
        }
        sum += std::stoi(values[i][j]);
      }
    }
    return sum;
  }

 private:
  vector<int> GetRange(const string& range) {
    vector<int> pos(4, 0);
    auto p = range.find_first_of(':');
    pos[0] = range[0] - 'A';
    pos[1] = std::stoi(range.substr(1, p - 1)) - 1;
    pos[2] = range[p + 1] - 'A' + 1;
    pos[3] = std::stoi(range.substr(p + 2));
    return pos;
  }
  int GetPosRes(const vector<vector<string>>& values, const string& s) {
    if (!(s[0] <= 'Z' && s[0] >= 'A')) {
      return std::stoi(s);
    }
    pair<int, int> p = {s[0] - 'A', stoi(s.substr(1)) - 1};
    return std::stoi(values[p.second][p.first]);
  }
  int GetRes(const vector<vector<string>>& values, int i, int j) {
    const string& tmp = values[i][j];
    auto pos =
        std::find_if(tmp.begin(), tmp.end(),
                     [](const auto& s) { return s == '+' || s == '-'; }) -
        tmp.begin() - 1;
    if (pos >= tmp.size() - 1) {
      return GetPosRes(values, tmp.substr(1));
    }
    int first = GetPosRes(values, tmp.substr(1, pos));
    int second = GetPosRes(values, tmp.substr(pos + 2));
    if (tmp[pos + 1] == '+') {
      return first + second;
    }
    return first - second;
  }
};
// 以下为考题输入输出框架，此部分代码不建议改动
template <typename T>
inline vector<T> ReadVector(int size) {
  vector<T> objects(size);
  for (int i = 0; i < size; ++i) {
    cin >> objects[i];
  }
  return objects;
}
int main() {
  int rows, cols;
  cin >> rows >> cols;
  vector<vector<string>> values;
  for (int i = 0; i < rows; i++) {
    vector<string> oneRow = ReadVector<string>(cols);
    values.push_back(oneRow);
  }
  string range;
  cin >> range;
  Solution solu;
  int result = solu.GetSum(values, range);
  cout << result << endl;
  return 0;
}
//该解法首先从输入参数range中解析出要遍历的选中区域的范围（开始结束行号和列号），存入一个vector变量pos中。
//接下来遍历所有选中区域的单元格：
// l  如果是公式，分别调用GetRes函数得到每个单元格的值。
// l  如果是值，直接调用std::stoi转换为整数即可。
//在函数GetRes内，调用find_if找到字符’+’或者’-‘的位置pos：
//Ø
//如果找不到，说明就直接等于某单元格的地址，再调用一次GetPosRes即可得到单元格的值。
//Ø
//如果找到，则根据pos从字符串中拆分出左右两个操作数，分别调用GetPosRes得到对应单元格的值first和second，最后执行相加或者相减。
//思路清晰，代码简洁，待改进之处：
// l  第62行违反编程规范：G.FMT.16-CPP
// 用空格突出关键字和重要信息，右括号')'前面不需要空格，会扣分。
